import common.CommonDemo;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Action;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.Assert;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import org.testng.annotations.TestInstance;

import java.time.Duration;
import java.util.Collections;

/**
 * 模拟鼠标操作
 */
public class ActionMouse {

    private CommonDemo commonDemo;
    private ChromeDriver driver;
    private String url;

    @BeforeTest
    public void setUp() {
        try {
            commonDemo = new CommonDemo();
            driver = commonDemo.getChromeDriver();
            url = commonDemo.getUserDir("src/main/resources/actionMouse.html");
            driver.get(url);
            driver.manage().window().maximize();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 模拟移动鼠标到指定元素，并点击左键且不释放左键点击动作
     */
    @Test
    public void clickHold() {
        new Actions(driver)
                .moveToElement(driver.findElement(By.id("news")))
                .clickAndHold()
                .perform();
    }

    /**
     * 模拟鼠标左键点击操作
     */
    @Test
    public void clickAndRelease(){
        new Actions(driver)
                .moveToElement(driver.findElement(By.id("news")))
                .click()
                .perform();
    }

    /**
     * 一个鼠标总共定义了5个按钮
     *  0 — Left Button (the default)
     *  1 — Middle Button (currently unsupported)
     *  2 — Right Button
     *  3 — X1 (Back) Button
     *  4 — X2 (Forward) Button
     */
    /**
     * 模拟鼠标右键操作
     */
    @Test
    public void contextClickButton(){
        WebElement element = driver.findElement(By.id("news"));
        new Actions(driver)
                .contextClick(element)
                .perform();
    }

    /**
     * 点击浏览器头部的“点击可后退”和“点击可前进”箭头按钮
     */
    @Test
    public void backClickElement(){
        try {
            //击浏览器头部的“点击可后退”按钮
            PointerInput pointerInput = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");
            Sequence backArrow = new Sequence(pointerInput, 0)
                    .addAction(pointerInput.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                    .addAction(pointerInput.createPointerUp(PointerInput.MouseButton.BACK.asArg()));
            Thread.sleep(2000);
            driver.perform(Collections.singletonList(backArrow));
            //击浏览器头部的“点击可前进”按钮
            Sequence forwardArrow = new Sequence(pointerInput, 0)
                    .addAction(pointerInput.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                    .addAction(pointerInput.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));
            Thread.sleep(2000);
            driver.perform(Collections.singletonList(forwardArrow));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * .doubleClick():模拟移动鼠标到指定元素并双击左键
     */
    @Test
    public void doubleClickDemo(){
        WebElement element = driver.findElement(By.id("news"));
        new Actions(driver)
                .doubleClick(element)
                .perform();
    }

    /**
     * 模拟鼠标移动到元素上，显示弹窗
     */
    @Test
    public void moveToElementDemo(){
        WebElement element = driver.findElement(By.xpath("//div[@id='pop']/a"));
        new Actions(driver)
                .moveToElement(element)
                .perform();
    }

    /**
     * moveToElement(WebElement target, int xOffset, int yOffset)
     * 以元素的视图中心点为原点，再按提供的偏移量移动鼠标
     */
    @Test
    public void offsetFromElement(){
        WebElement element = driver.findElement(By.xpath("//div[@id='pop']/a"));
        new Actions(driver)
                .moveToElement(element)
                .pause(Duration.ofSeconds(1))
                .moveToElement(element, 300, 0)
                .perform();
    }

    /**
     * offsetFromViewport ：从可视界面的左上角移动鼠标到指定偏移量
     */
    @Test
    public void offsetFromViewport(){
        try {
            PointerInput pointerInput = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");
            Sequence sequence = new Sequence(pointerInput, 0)
                    .addAction(pointerInput.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 100,30));
//        ((RemoteWebDriver)driver).perform(Collections.singletonList(sequence));
            driver.perform(Collections.singletonList(sequence));
            Thread.sleep(1000);
            Sequence sequence1 = new Sequence(pointerInput, 0)
                    .addAction(pointerInput.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 1,150));
//        ((RemoteWebDriver)driver).perform(Collections.singletonList(sequence));
            driver.perform(Collections.singletonList(sequence1));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    /**
     * offsetFromCurrentPointer：将鼠标从当前位置移动到用户提供的偏移量，如果之前没有移动过鼠标，则起始位置位于视窗的左上角，
     * note：当页面滚动时，指针的位置不会改变
     */
    @Test
    public void offsetFromCurrentPointer(){
        //移动到指定位置，显示pop弹窗
        new Actions(driver)
                .pause(Duration.ofSeconds(2))
                .moveByOffset(100, 30)
                .perform();
        //移动到其他位置，pop弹窗也随之隐藏
        new Actions(driver)
                .pause(Duration.ofSeconds(2))
                .moveByOffset(1,150)
                .perform();
    }

    @AfterTest
    public void tearDown() {
        try {
            Thread.sleep(2000);
            driver.quit();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
